home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / Apps / ScreenSavers / BackSpaceViews / StarShipView.BackModule / Celestial.bproj / Body.m < prev    next >
Encoding:
Text File  |  1995-06-12  |  7.3 KB  |  302 lines

  1. #import "Body.h"
  2.  
  3. @implementation Body
  4.  
  5. - init
  6. {
  7.     [super init];
  8.  
  9.     bodyDelta = maskDelta = 1;  //must not be < 1
  10.     maskDist = bodyDist = 1;
  11.     currentBodyListIndex = 0;
  12.     bodyFrameIndexCounter = maskFrameIndexCounter = 0;
  13.     bodyFrameRect.origin.x = 0.0;
  14.     bodyFrameRect.origin.y = 0.0;
  15.     maskFrameRect.origin.x = 0.0;
  16.     maskFrameRect.origin.y = 0.0;
  17.     firstState = YES;
  18.  
  19.     return self;
  20. }
  21.  
  22. - (BOOL)doUntilDone
  23. {
  24. BOOL maskDone;
  25.     maskDone = NO;
  26.     if(firstState){
  27.         currentImage = [self setBodyImage];
  28.         [self setFrameRectForBody]; //set frame size
  29.         [self setFrameRectForMask];        
  30.         [self setStartPosition:centerOfScreen];  //first body and mask position
  31.  
  32.         firstState = NO;
  33.  
  34.         [self drawBody];
  35.         [self setImageListIndex];
  36.         currentImage = [self setBodyImage];
  37.         [self setFrameRectForBody]; //set frame size
  38.         bodyPosition = [self adjustPositionForBody: bodyPosition];
  39.     }
  40.     else {
  41.         
  42.         maskDone = [self eraseBody];
  43.         [self setFrameRectForMask];        
  44.         maskPosition = [self adjustPositionForMask: maskPosition];
  45.         //draw body
  46.         [self drawBody];
  47.         [self setImageListIndex];
  48.         currentImage = [self setBodyImage];
  49.         [self setFrameRectForBody]; //set frame size
  50.         bodyPosition = [self adjustPositionForBody: bodyPosition];
  51.     }
  52.  
  53.     if(maskDone){
  54.         return YES; //this body done
  55.     }    
  56.     else{
  57.         return NO;
  58.     }
  59. }
  60. - setImageListIndex
  61. {
  62.     currentBodyListIndex =  floor((bodyFrameIndexCounter * frameDelta) *
  63.     (bodyFrameIndexCounter * frameDelta) *
  64.     (bodyFrameIndexCounter * frameDelta) *
  65.     (bodyFrameIndexCounter * frameDelta));
  66.     bodyFrameIndexCounter++;
  67.     if(currentBodyListIndex >= numberOfFrames - 1)
  68.         currentBodyListIndex = numberOfFrames - 1;
  69.      return self;
  70. }    
  71.  
  72.  
  73. //        4
  74. //uses X to make expotential curve for calculating movement of object
  75. //idea was to start slow and speed up expotentially
  76. //the smaller the value of objectSpeed the faster the object moves
  77. //I.E. if the number is 2 then it take 2 steps to move the whole distance    
  78. - setObjectSpeed:(float)objectSpeed
  79. {
  80. float radius,x,y;
  81.  
  82.  
  83.     x = bounds.size.width;
  84.     y = bounds.size.height;
  85.     radius = (sqrt(x*x + y*y))/2;  // of screen bounds
  86.  
  87.     distDelta = (sqrt(sqrt(radius)))/(1 + objectSpeed);
  88.  
  89.     frameDelta = (sqrt(sqrt(numberOfFrames)))/(1 + objectSpeed);
  90.  
  91.     return self;
  92. }            
  93.  
  94. - free
  95. {
  96.     return [super free];
  97. }
  98.  
  99. - (NXImage *)setBodyImage
  100. {
  101.     return ([imageList objectAt:currentBodyListIndex]);    
  102.  
  103. }
  104.  
  105. - setImageList:(List *)list
  106. {
  107.  
  108.     imageList = list;
  109.         return self;
  110. }
  111.  
  112. - setMaskList:(List *)list
  113. {
  114.     maskList = list;
  115.     return self;
  116. }
  117.  
  118. - setNumberOfFrames
  119. {
  120.     numberOfFrames = [imageList count];
  121.     return self;
  122. }
  123. - setStartPosition:(NXPoint)point  //where body starts out
  124. {
  125.     bodyPosition.x = point.x - floor((bodyFrameRect.size.width / 2));
  126.     bodyPosition.y = point.y - floor((bodyFrameRect.size.height / 2));
  127.     maskPosition.x = point.x - floor((maskFrameRect.size.width / 2));
  128.     maskPosition.y = point.y - floor((maskFrameRect.size.height / 2));
  129.     return self;
  130. }
  131.  
  132.  
  133. - setStarsOutlet: (id)starsOutlet
  134. {
  135.     starsObject = starsOutlet;
  136.     return self;
  137. }
  138.  
  139. - setFrameRectForBody
  140. {
  141. NXSize size;
  142.     [currentImage getSize: &size];
  143.     
  144.     //adjust the rectangle to reflect actual image that was built
  145.     // so that you know when it actually crosses the viewscreen
  146.         
  147.     bodyFrameRect.origin.x = 8.0;
  148.     bodyFrameRect.origin.y = 8.0;
  149.     bodyFrameRect.size.width = size.width-16;
  150.     bodyFrameRect.size.height = size.height-16;
  151.     return self;
  152. }
  153.  
  154. - setFrameRectForMask
  155. {
  156.     maskFrameRect.size.width = bodyFrameRect.size.width;
  157.     maskFrameRect.size.height = bodyFrameRect.size.height;
  158.     return self;
  159. }
  160.  
  161. //bodyFrameRect is actual size of real image inside a black image
  162. // 8 pixels bigger on all sides
  163. //bodyPosition is where the actual image will be composited
  164.  
  165. - drawBody
  166. {
  167.  
  168. NXPoint offset;
  169. NXRect adjustedRect={0.0,0.0,bodyFrameRect.size.width+16,
  170. bodyFrameRect.size.height+16};
  171.  
  172.     if (bodyPosition.x  < (bounds.size.width + bodyFrameRect.size.width) &&
  173.         bodyPosition.x > (bounds.origin.x - (bodyFrameRect.size.width + 1)) &&
  174.         bodyPosition.y  < (bounds.size.height + bodyFrameRect.size.width) &&
  175.         bodyPosition.y > (bounds.origin.y-(bodyFrameRect.size.height + 1))){
  176.  
  177.  
  178.     [self setVoidRect:bodyIndex];
  179.         
  180.     offset.x = bodyPosition.x - 8;
  181.     offset.y = bodyPosition.y - 8;
  182.  
  183.     [currentImage composite:NX_COPY fromRect:&adjustedRect
  184.      toPoint:&offset];
  185.     }
  186.  
  187.     return self;
  188. }
  189.  
  190. - (BOOL)eraseBody
  191. {
  192. NXRect maskRect;
  193.  
  194.     if (maskPosition.x  < (bounds.size.width  + maskFrameRect.size.width) &&
  195.     maskPosition.x > (bounds.origin.x-(maskFrameRect.size.width + 1)) &&
  196.     maskPosition.y  < (bounds.size.height + maskFrameRect.size.width) &&
  197.     maskPosition.y > (bounds.origin.y -(maskFrameRect.size.height + 1))){
  198.     
  199.         maskRect.origin.x = maskPosition.x;
  200.         maskRect.origin.y = maskPosition.y;
  201.         maskRect.size.width = maskFrameRect.size.width;
  202.         maskRect.size.height = maskFrameRect.size.height;
  203.  
  204.         PSsetgray(0);
  205.         NXRectFill(&maskRect);
  206.         return NO;
  207.     }
  208.     else{
  209.         return YES;
  210.     }
  211. }
  212. //figure out new x,y position for moving object
  213. - (NXPoint)adjustPositionForBody:(NXPoint)position 
  214. {
  215.     bodyDist = floor((distDelta * bodyDelta) * (distDelta * bodyDelta) * (distDelta * bodyDelta) * (distDelta * bodyDelta));
  216.     bodyDelta++;    
  217.     position.x = floor((centerOfScreen.x - (bodyFrameRect.size.width / 2))
  218.      + (bodyDist * cos(theta)));
  219.     position.y = floor((centerOfScreen.y - (bodyFrameRect.size.height / 2))
  220.      + (bodyDist * sin(theta)));
  221.     return position;
  222. }
  223.  
  224. - (NXPoint)adjustPositionForMask:(NXPoint)position 
  225. {
  226.         maskDist = floor((distDelta * maskDelta) * (distDelta * maskDelta) * (distDelta * maskDelta) * (distDelta * maskDelta));
  227.     maskDelta++;
  228.  
  229.     position.x = floor((centerOfScreen.x - (maskFrameRect.size.width / 2))
  230.      + (maskDist * cos(theta)));
  231.     position.y = floor((centerOfScreen.y - (maskFrameRect.size.height / 2))
  232.      + (maskDist * sin(theta)));
  233.     return position;
  234. }
  235.  
  236.  
  237. //assumes position and size rects have been set for mask and body
  238. - setVoidRect:(int)index
  239. {
  240. AvoidStruct avoidStruct;
  241. const NXRect bodyRect = {bodyPosition.x,bodyPosition.y,
  242. bodyFrameRect.size.width,bodyFrameRect.size.height};
  243.  
  244.     //actual image is centered in a black rectangle 8 pixels
  245.     //bigger in each direction
  246.     //since bodyPosition and bodyFrameRect are set to the image
  247.     // that is in the oversized rect, adjust avoidance to
  248.     // real origin of black rectangle and make width and height
  249.     // actual image size plus 8 pixels - this makes the assumption
  250.     //stars are drawn from 0,0 to 8 pixels right and up.
  251.     
  252.     avoidStruct.avoid.origin.x = bodyRect.origin.x-8;
  253.     avoidStruct.avoid.origin.y = bodyRect.origin.y-8;
  254.     avoidStruct.avoid.size.width = bodyRect.size.width+8;    
  255.     avoidStruct.avoid.size.height = bodyRect.size.height+8;
  256.     [avoidStorage replaceElementAt:(unsigned int)bodyIndex with:&avoidStruct];
  257.     return self; 
  258. }
  259. - setBoundsRect:(NXRect *)r
  260. {
  261.  
  262. // screen border width is 5 pixels
  263. // make ship bounds 1 pixel less so that
  264. // when border shrinks by 1 it won't
  265. // affect objects - bounds will catch up
  266.  
  267.     NXSetRect(&bounds,
  268.     r->origin.x,
  269.     r->origin.y,
  270.     r->size.width,
  271.     r->size.height);
  272.     [self setCenter]; 
  273.     return self;
  274. }
  275. - setCenter
  276. {
  277.     centerOfScreen.x = (bounds.size.width / 2) + bounds.origin.x;
  278.      centerOfScreen.y = bounds.size.height / 2 + bounds.origin.y;
  279.     return self;
  280. }
  281.  
  282. - setAngle:(float)angle;
  283. {
  284.     theta = angle;
  285.     return self;
  286.  
  287. }
  288. - setAvoidStorage:(Storage *)storageObject
  289. {
  290.     avoidStorage = storageObject;
  291.     return self;
  292. }
  293.  
  294. - setBodyIndex:(int)index
  295. {
  296.     bodyIndex = index;
  297.     return self;
  298. }
  299.  
  300.  
  301. @end
  302.